﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Configuration;
using HR.Appointments.Service;

/// <summary>
/// Handles access to the service layer and authentication for web pages.
/// </summary>
public class WebPage : System.Web.UI.Page
{
    #region Protected Member 
    protected const string LOGIN_REDIRECT_PAGE = "~/Login.aspx";
    #endregion

    #region Private Members
    private const string MAIN_REDIRECT_PAGE = "~/Company.aspx";
    private const string USERNAME = "Userwame";
    private const string PASSWORD = "Password";
    private const string COMPANY_ID = "CompanyId";
    private const string LOGGED_IN_STATUS = "LoggedInStatus";
    private const string COOKIE_NAME = "OrderInfo";
    private ServiceFacade _facade;
    private string _cookieName;
    private bool _isLoggedIn = false;
    private int _cookieDelayTime = 5; //Default minutes
    #endregion

    #region Constructors
    public WebPage()
	{
        _facade = new ServiceFacade(true);
        _cookieDelayTime = 
            Convert.ToInt32(ConfigurationManager.AppSettings["CookieDeleteTime"].ToString());
    }
    #endregion

    #region Protected Properties
    /// <summary>
    /// Get the facade for the service layer.
    /// All calls from the web to the servicelayer should go through this property.
    /// </summary>
    protected ServiceFacade Facade
    {
        get { return _facade; }
    }

    /// <summary>
    /// Get name of the cookie holding the user and company info
    /// </summary>
    protected string CookieName
    {
        get { return COOKIE_NAME; }
    }

    /// <summary>
    /// Checks the cookie for username and password and also saves the companyid 
    /// to the cookie (see GetCompanyIdFromCookie).
    /// </summary>
    /// <returns>Returns true if cookie is found and credentials have been validated.</returns>
    protected bool IsLoggedIn
    {
        get { return IsLoggedInMethod(); }
    }

    protected bool IsAdmin
    {
        get { return IsAdminMethod(); }
    }
    #endregion

    #region Protected Methods
    /// <summary>
    /// Save the user credentials so we can access access restriced pages.
    /// </summary>
    /// <param name="username">Name of the user who is logging on</param>
    /// <param name="password">Password of the user</param>
    protected void Logon(string username, string password)
    {
        HttpCookie cookie = Response.Cookies[CookieName];
        if(cookie == null)
        {
            cookie = new HttpCookie(CookieName);
            Response.Cookies.Add(cookie);
        }
        cookie.Values[USERNAME] = username;
        cookie.Values[PASSWORD] = password;
        cookie.Values[LOGGED_IN_STATUS] = true.ToString();
        cookie.Expires = DateTime.Now.AddMinutes(_cookieDelayTime); //DelayTime set in app settnings
    }

    /// <summary>
    /// Delete credentials if user logs off.
    /// </summary>
    protected void LogOff()
    {
        Response.Cookies[CookieName].Values[LOGGED_IN_STATUS] = false.ToString();
        Response.Cookies[CookieName].Expires = DateTime.Now;
        Request.Cookies[CookieName].Expires = DateTime.Now;
    }

    /// <summary>
    /// Save the companyId for easy retrieval.
    /// </summary>
    /// <param name="id">Id of the company as string</param>
    protected void SetCompanyIdToCookie(string id)
    {
        System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(id), "CompanyId is Empty");
        SetCompanyIdToCookie(Convert.ToInt32(id));
    }

    /// <summary>
    /// Save the companyId for easy retrieval.
    /// </summary>
    /// <param name="id">Id of the company</param>
    protected void SetCompanyIdToCookie(int id)
    {
        System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(CookieName), "CookieName is Empty");

        HttpCookie companyCookie = Request.Cookies.Get(CookieName);
        if (companyCookie == null)
        {
            companyCookie = new HttpCookie(CookieName);
        }
        companyCookie.Values[COMPANY_ID] = id.ToString();
        Response.Cookies.Add(companyCookie);
    }

    /// <summary>
    /// Store the companyid for the user who is logged in.
    /// </summary>
    /// <returns></returns>
    protected int GetCompanyIdFromCookie()
    {
        string result = "0";
        HttpCookie companyCookie = Request.Cookies.Get(CookieName);
        if (companyCookie != null)
        {
            result = companyCookie.Values[COMPANY_ID];
            if (!string.IsNullOrEmpty(result))
            {
                return Convert.ToInt32(result);
            }
        }
        Redirect();
        throw new System.Exception("Page should have beed redirected");
    }

    protected void Redirect()
    {
        if (IsLoggedIn)
        {
            Response.Redirect(LOGIN_REDIRECT_PAGE);
        }
        else
        {
            Response.Redirect(MAIN_REDIRECT_PAGE);
        }
    }

    protected virtual void SetCookieName(string name)
    {
        _cookieName = name;
    }
    #endregion

    #region Private method
    private bool IsLoggedInMethod()
    {
        HttpCookie cookie = Request.Cookies.Get(CookieName);
        if (cookie != null)
        {
            string username = cookie.Values[USERNAME];
            string password = cookie.Values[PASSWORD];
            bool loggedOn = Convert.ToBoolean(cookie.Values[LOGGED_IN_STATUS]);

            if (!loggedOn)
                return false;

            if (!string.IsNullOrEmpty(username) &&
                !string.IsNullOrEmpty(password))
            {
                //TODO:Split into 2 methods.  One to validate, other to get companyId
                //HACK:Company id should not be set here.  Need better design and then refactor.
                int companyId = Facade.Employee().ValidCredentialsThenGetCompanyId(username, password);
                if (companyId != 0)
                {
                    SetCompanyIdToCookie(companyId);
                    cookie.Expires = DateTime.Now.AddMinutes(_cookieDelayTime);
                    return true;
                }
            }
        }
        return false;
    }
    private bool IsAdminMethod()
    {
        HttpCookie cookie = Request.Cookies.Get(CookieName);
        if (cookie != null)
        {
            string username = cookie.Values[USERNAME];
            string password = cookie.Values[PASSWORD];

            if (!string.IsNullOrEmpty(username) &&
                !string.IsNullOrEmpty(password))
            {
                if (string.Compare(username, "admin") == 0 &&
                    string.Compare(password, "admin") == 0)
                {
                    return true;
                }
            }
        }
        return false;
    }
    #endregion
}
